const _ = require("lodash");

const fs = require("fs");

// prettier-ignore
const { readAllValues } = require("../awakened-potential/helpers/readAllValues.js");

// 获取所有分组杀前组准确性方法
const getKillPreviousGroupAccuracy = require("./utils/getKillPreviousGroupAccuracy.js");

const getNumberGroupMap = require("../awakened-potential/modules/cjs/getNumberGroupMap.js");

const { allNumbers } = require("./utils/constant.js");

const checkAccuracy = require("./utils/checkAccuracy.js");
// 评分函数
const calculateScore = require("./utils/calculateScore.js");
// 计算正确段和错误段的总长度
const calcTotalLength = require("./utils/calcTotalLength.js");

// 计算准确性统计信息
// prettier-ignore
const { calcAccuracySummary, ACCURACY_SUMMARY_CN_MAP } = require("./utils/calcAccuracySummary.js");

// 读取所有期数数据
const allValues = readAllValues("m"); // .slice(0, 1000);

// 读取所有分组数据
const groupsObject = require("./group.js");

// prettier-ignore
const killPreviousGroupAccuracyObject = getKillPreviousGroupAccuracy(allValues, groupsObject); // 获取所有分组杀前组准确性对象

// 📦 引入生成号码与子分组映射的工具
const numberGroupMap = getNumberGroupMap(allNumbers, groupsObject);

// #region 检查分组准确性数组长度
const expectedLength = allValues.length - 1;
for (const key of Object.keys(killPreviousGroupAccuracyObject)) {
  if (killPreviousGroupAccuracyObject[key].length !== expectedLength) {
    // prettier-ignore
    console.error(`❌ 分组 ${key} 的准确性数组长度为 ${killPreviousGroupAccuracyObject[key].length}，应为 ${expectedLength}，数据异常，程序退出。`);
    process.exit(1);
  }
}
console.log(`✅ 所有分组准确性数组长度校验通过。${expectedLength}`);
// #endregion

// ✅ 滑动窗口开关
const useWindow = true;
// ✅ 滑动窗口大小
const windowSize = 100;
// 基础历史数据长度
const baseHistoryDataLength = 100;

// 假设 calcAccuracySummary 函数返回的 stats 包含以下字段：
// accuracy：准确率
// maxConsecutiveErrors：最大连续错误次数
// isTrendDetected：趋势检测结果
// systemErrorCount：系统性错误次数
// randomErrorCount：偶然错误次数
// isHighErrorMode：是否处于高误差模式

const getBestGroupFromPostStats = (postStatSelectionItems) => {
  // 先筛选掉高误差模式的组
  // const validGroups = postStatSelectionItems.filter(
  //   (item) => !item.stats.isHighErrorMode
  // );

  // if (validGroups.length === 0) {
  //   console.log("没有符合条件的组，所有组都属于高误差模式");
  //   return null; // 没有符合条件的组
  // }

  // 按照多级排序，按优先级排序：
  const sortedGroups = _.sortBy(postStatSelectionItems, (item) => [
    -item.stats.accuracyRate, // 优先考虑准确率
    -item.stats.maxConsecutiveCorrect, // 然后考虑最大连续正确次数
    item.stats.maxConsecutiveIncorrect, // 然后考虑最大连续错误次数（越少越好）
    item.stats.systemErrorCount, // 系统性错误次数越少越好
    item.stats.randomErrorCount, // 偶然错误次数越少越好
    -item.stats.isTrendDetected, // 如果检测到趋势，优先考虑
    -item.stats.count, // 最后考虑统计次数，次数多的组通常更稳定
  ]);

  // 获取排序后的最佳组
  const bestGroup = sortedGroups[0];

  // prettier-ignore
  // console.log(`选择的最佳组: ${bestGroup.group_name}, 准确率: ${bestGroup.stats.accuracyRate}%`);

  return bestGroup;
};

const isAccurateResult = [];

allValues.forEach((item, index) => {
  // 获取前一期号码
  const prevItem = allValues[index - 1];

  // prettier-ignore
  const historyValues =  allValues.slice(0, index) // 不包含index位置的元素

  if (historyValues.length < baseHistoryDataLength) return;

  // todo: 是否保留?
  // prettier-ignore
  const temp = useWindow ? _.takeRight(historyValues, windowSize) : historyValues

  // todo: 先切数据，后续其他: 例如计算 weights
  // prettier-ignore
  const postStatSelectionItems = _.map(_.toPairs(killPreviousGroupAccuracyObject), ([group_name, accuracy_array]) => {

  // prettier-ignore
    const stats = calcAccuracySummary(accuracy_array.slice(useWindow ? index - windowSize : 0, index));

     // 计算该组的评分
     const score = calculateScore(group_name, stats);

    return { group_name, accuracy_array, stats, score }
  });

  // console.log(postStatSelectionItems)

  // 按照得分排序，选择得分最高的组
  const bestGroup = _.maxBy(postStatSelectionItems, "score");
  // 最终选择的分组
  let finalSelectedGroup = null;

  if (bestGroup.score === -Infinity) {
    // 当得分为 -Infinity 时，执行多级排序
    // prettier-ignore
    // console.log("该组得分为负无穷大（-Infinity），正在执行多级排序选择最优组...");
    const selectedGroup = getBestGroupFromPostStats(postStatSelectionItems);

    // 输出最终选择的组信息
    if (selectedGroup) {
      // prettier-ignore
      // console.log(`最终选择的最佳组: ${selectedGroup.group_name}, 得分: ${selectedGroup.stats.accuracyRate}`);
      finalSelectedGroup = selectedGroup;
    } else {
      // 如果没有选出最佳组，报错并退出
      console.error("未能选出最佳组，程序即将退出。");
      process.exit(1);
    }
  } else {
    // 输出最合适的组信息
    // prettier-ignore
    // console.log(`选择的最佳组: ${bestGroup.group_name}, 得分: ${bestGroup.score}`);
    finalSelectedGroup = bestGroup;
  }

  // 输出最终选择的组信息
  // console.log(`最终选择的最佳组: ${finalSelectedGroup.group_name}, 得分: ${finalSelectedGroup.stats.accuracyRate}`);
  // 计算“幸运号”——即所有号码中未被当前最佳分组包含的号码
  // const luck = _.difference(allNumbers, _.flatten(groupsObject[finalSelectedGroup.group_name]));

  // 获取前一期号码所在的子分组索引
  // prettier-ignore
  const prevSubGroupIndex = numberGroupMap[prevItem.number]?.[finalSelectedGroup.group_name];

  // 获取前一期号码所在的子分组数据
  // prettier-ignore
  const prevSubGroup = groupsObject[finalSelectedGroup.group_name][prevSubGroupIndex];

  // 从 allNumbers 中去除 prevSubGroup 中的元素
  const luck = allNumbers.filter((num) => !prevSubGroup.includes(num));

  // 计算“选出来的号码”是否准确
  const isAccurate = checkAccuracy(luck, item.number);

  // isAccurate
  isAccurateResult.push(isAccurate);

  // todo: 预测下期的话，需要获取temp的最后takeRight(n)个元素
});

// console.log(killPreviousGroupAccuracyObject)

// #region 检查分组准确性数组长度
/*
// 将对象转换为数组
// prettier-ignore
const resultArray = _.map(_.toPairs(killPreviousGroupAccuracyObject), ([group_name, accuracy_array]) => {
  return { group_name, accuracy_array }
});

const temp_accuracy_summary = calcAccuracySummary(resultArray[1].accuracy_array);

console.log(resultArray[1].accuracy_array)

// 输出翻译后的统计信息
const translatedSummary = {};
Object.keys(temp_accuracy_summary).forEach(key => {
  // 使用 ACCURACY_SUMMARY_CN_MAP 将字段名称映射为中文
  translatedSummary[ACCURACY_SUMMARY_CN_MAP[key] || key] = temp_accuracy_summary[key];
});

console.log(translatedSummary);
//*/
// #endregion


// #region 输出预测结果
//*
// 将 isAccurateResult 写入文件，文件名为 temp_accuracy_result.json
// prettier-ignore
// fs.writeFileSync('temp_accuracy_result.json', JSON.stringify(isAccurateResult), 'utf-8');

const temp_accuracy_summary = calcAccuracySummary(isAccurateResult);
// const temp_accuracy_summary = calcAccuracySummary([1,1,0,0,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1]);

console.log(`isAccurateResult.length: ${isAccurateResult.length}`);

// 输出翻译后的统计信息
const translatedSummary = {};
Object.keys(temp_accuracy_summary).forEach((key) => {
  // 使用 ACCURACY_SUMMARY_CN_MAP 将字段名称映射为中文
  // prettier-ignore
  translatedSummary[ACCURACY_SUMMARY_CN_MAP[key] || key] = temp_accuracy_summary[key];
});

console.log(translatedSummary);

// prettier-ignore
const totalCorrectLength = calcTotalLength(translatedSummary['连续正确段长度频率']);
// prettier-ignore
const totalIncorrectLength = calcTotalLength(translatedSummary['连续错误段长度频率']);
const totalLength = totalCorrectLength + totalIncorrectLength;

console.log("正确段总长度：", totalCorrectLength);
console.log("错误段总长度：", totalIncorrectLength);
console.log("正确段和错误段总长度之和：", totalLength);
//*/
// #endregion
